#include "MainWindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
      ,   m_output(0)
{
/*
 * A ideia aqui é criar uma main window com duas sub-widgets, que são as duas GUIs
 * dos dois canais.
 */
    central_widget = new QWidget;

    setCentralWidget(central_widget);
    statusBar()->show();


    hor_box = new QHBoxLayout;
    ver_box = new QGridLayout;
    bottom_hor_box = new QHBoxLayout;


    left_channel = new GUI;
    right_channel = new GUI;
    hor_box->addWidget(left_channel);
    hor_box->addWidget(right_channel);

// top stuff
    top_label = new QLabel(tr("<h1> <b> <center> AudioTest</b></h1>"));
    top_label2 = new QLabel(tr("<h5> <center> N&N Tech </h5>"));
    ver_box->addWidget(top_label, 0,0);
    ver_box->addWidget(top_label2, 1,0);
//	ver_box->addStretch();
    ver_box->addLayout(hor_box, 2,0);


// bottom stuff
    play_button = new QPushButton(tr("&Iniciar Som"));
    stop_button = new QPushButton(tr("&Parar Som"));
    play_button->setIcon(QIcon(":/images/play.png"));
    stop_button->setIcon(QIcon(":/images/stop.png"));
    bottom_hor_box->addWidget(play_button);
    bottom_hor_box->addWidget(stop_button);
    ver_box->addLayout(bottom_hor_box, 3,0);

    bottom_plotter_box = new QHBoxLayout;
    HarryPlotter_OD = new plotter(this);
    HarryPlotter_OE = new plotter(this);
    bottom_plotter_box->addWidget(HarryPlotter_OD);
    bottom_plotter_box->addWidget(HarryPlotter_OE);
    ver_box->addLayout(bottom_plotter_box, 4, 0);

    central_widget->setLayout(ver_box);

    //menu

    Arquivo = menuBar()->addMenu(tr("&Arquivo"));
    Exit = new QAction(tr("Sai&r"), this);
    Exit->setStatusTip(tr("Sair do Programa"));

    Arquivo->addAction(Exit);
    connect(Exit, SIGNAL(triggered()), this, SLOT(close()));


    Editar = menuBar()->addMenu(tr("&Editar"));

    Visualizar = menuBar()->addMenu(tr("&Visualizar"));

    Ferramentas = menuBar()->addMenu(tr("&Ferramentas"));

    Ajuda = menuBar()->addMenu(tr("A&juda"));


    // End of Menu

    // Starting generator

    connect(play_button, SIGNAL(clicked()), this, SLOT(start_sound()));
    connect(stop_button, SIGNAL(clicked()), this, SLOT(stop_sound()));
}

MainWindow::~MainWindow()
{

}

void MainWindow::audio_initializing(){

    m_pullTimer = new QTimer(this);
    m_device = QAudioDeviceInfo::defaultOutputDevice();
    m_buffer = QByteArray(32768, 0);
    m_audioOutput = new QAudioOutput;
//	m_output = new QIODevice;

    connect(m_pullTimer, SIGNAL(timeout()), this, SLOT(pullTimerExpired()));

    m_pullMode = true;

    m_format.setSampleRate(44100);
    m_format.setChannelCount(2);
    m_format.setSampleSize(16);
    m_format.setCodec("audio/pcm");
    m_format.setByteOrder(QAudioFormat::LittleEndian);
    m_format.setSampleType(QAudioFormat::SignedInt);

    QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
    if (!info.isFormatSupported(m_format)) {
        m_format = info.nearestFormat(m_format);
    }

    if (left_channel->use_white_noise->isChecked()){
        if(right_channel->use_white_noise->isChecked()){
            m_generator = new Generator(m_format, 1000000, -1, (left_channel->level), -1, (right_channel->level), this);
        }
        else {
            m_generator = new Generator(m_format, 1000000, -1, (left_channel->level), right_channel->frequency, (right_channel->level), this);
        }
    }
    else {
        if(right_channel->use_white_noise->isChecked()){
            m_generator = new Generator(m_format, 1000000, left_channel->frequency, (left_channel->level), -1, (right_channel->level), this);
        }
        else{
            m_generator = new Generator(m_format, 1000000, left_channel->frequency, (left_channel->level), right_channel->frequency, (right_channel->level), this);
        }
    }

    delete m_audioOutput;
    m_audioOutput = 0;
    m_audioOutput = new QAudioOutput(m_device, m_format, this);
//	connect(m_audioOutput, SIGNAL(notify()), SLOT(notified()));
    m_generator->open(QIODevice::ReadOnly);


}

void MainWindow::start_sound(){
    this->audio_initializing();
//    HarryPlotter = new plotter(m_generator->ydata1, this);
//    ver_box->addWidget(HarryPlotter, 5,0);
//    ver_box->update();

//    qWarning() << "Audio Status: " << m_audioOutput->state();

    if (m_audioOutput->state() == QAudio::SuspendedState){
        m_audioOutput->start(m_generator);
        play_button->setDisabled(true);
        stop_button->setDisabled(false);
    }
    else if (m_audioOutput->state() == QAudio::ActiveState){
        m_audioOutput->stop();
        stop_button->setDisabled(true);
        play_button->setDisabled(false);
    }
    else if (m_audioOutput->state() == QAudio::StoppedState){
        m_audioOutput->start(m_generator);
        play_button->setDisabled(true);
        stop_button->setDisabled(false);
    }
}

void MainWindow::stop_sound(){
//	delete HarryPlotter;

    if (m_audioOutput->state() == QAudio::SuspendedState){
        m_audioOutput->start(m_generator);
        play_button->setDisabled(true);
        stop_button->setDisabled(false);
    }
    else if (m_audioOutput->state() == QAudio::ActiveState){
        m_audioOutput->stop();
        stop_button->setDisabled(true);
        play_button->setDisabled(false);
    }
    else if (m_audioOutput->state() == QAudio::StoppedState){
        m_audioOutput->start(m_generator);
        play_button->setDisabled(true);
        stop_button->setDisabled(false);
    }
}

void MainWindow::pullTimerExpired()
{
    if (m_audioOutput && m_audioOutput->state() != QAudio::StoppedState) {
        int chunks = m_audioOutput->bytesFree()/m_audioOutput->periodSize();
        while (chunks) {
           const qint64 len = m_generator->read(m_buffer.data(), m_audioOutput->periodSize());
           if (len)
               m_output->write(m_buffer.data(), len);
           if (len != m_audioOutput->periodSize())
               break;
           --chunks;
        }
    }
}
